using System;
using System.Collections.Generic;
using System.Text;

namespace Vj.MyMath
{
    /// <summary>
    /// Used for 3x3 Transformation Matrix operations
    /// </summary>
    public class TransformationMatrixHelper
    {

        public static MatrixDouble GetXRotMatrix(double angle)
        {
            MatrixDouble xRotM = new MatrixDouble(4, 4);
            double angleRad = angle * (Math.PI / 180.0);

            xRotM[0, 0] = 1;
            xRotM[1, 1] = Math.Cos(angleRad);
            xRotM[1, 2] = -Math.Sin(angleRad);
            xRotM[2, 1] = Math.Sin(angleRad);
            xRotM[2, 2] = Math.Cos(angleRad);
            xRotM[3, 3] = 1;

            return xRotM;
        }

        public static MatrixDouble GetYRotMatrix(double angle)
        {
            MatrixDouble yRotM = new MatrixDouble(4, 4);
            double angleRad = angle * (Math.PI / 180.0);

            yRotM[0, 0] = Math.Cos(angleRad);
            yRotM[0, 2] = Math.Sin(angleRad);
            yRotM[1, 1] = 1;
            yRotM[2, 0] = -Math.Sin(angleRad);
            yRotM[2, 2] = Math.Cos(angleRad);
            yRotM[3, 3] = 1;

            return yRotM;
        }

        public static MatrixDouble GetZRotMatrix(double angle)
        {
            MatrixDouble zRotM = new MatrixDouble(4, 4);
            double angleRad = angle * (Math.PI / 180.0);

            zRotM[0, 0] = Math.Cos(angleRad);
            zRotM[0, 1] = -Math.Sin(angleRad);
            zRotM[1, 0] = Math.Sin(angleRad);
            zRotM[1, 1] = Math.Cos(angleRad);
            zRotM[2, 2] = 1;
            zRotM[3, 3] = 1;

            return zRotM;
        }

        public static MatrixDouble GetRotMatrix(double x, double y, double z, double angle)
        {
            // normalize x,y,z

            MatrixDouble rotM = new MatrixDouble(4, 4);
            double angleRad = angle * (Math.PI / 180.0);

            double t = 1 - Math.Cos(angleRad);
            double c = Math.Cos(angleRad);
            double s = Math.Sin(angleRad);

            rotM[0, 0] = t * x * x + c;
            rotM[1, 0] = t * x * y - s * z;
            rotM[2, 0] = t * x * y + s * y;
            rotM[0, 1] = t * x * y + s * z;
            rotM[1, 1] = t * y * y + c;
            rotM[2, 1] = t * y * z - s * x;
            rotM[0, 2] = t * x * z - s * y;
            rotM[1, 2] = t * y * z + s * x;
            rotM[2, 2] = t * z * z + c;
            rotM[3, 3] = 1;


            return rotM;
        }

        public static MatrixDouble GetScaleMatrix(double scaleFactor)
        {
            MatrixDouble scaleM = new MatrixDouble(4, 4);

            scaleM[0, 0] = scaleFactor;
            scaleM[1, 1] = scaleFactor;
            scaleM[2, 2] = scaleFactor;
            scaleM[3, 3] = 1;

            return scaleM;
        }

        public static MatrixDouble GetTranslationMatrix(double x, double y, double z)
        {
            MatrixDouble transM = new MatrixDouble(4, 4);

            transM[0, 3] = x;
            transM[1, 3] = y;
            transM[2, 3] = z;
            transM[0, 0] = 1;
            transM[1, 1] = 1;
            transM[2, 2] = 1;
            transM[3, 3] = 1;

            return transM;
        }

        public static MatrixDouble GetIdentityMatrix()
        {
            MatrixDouble identityM = new MatrixDouble(4, 4);
            identityM[0, 0] = 1;
            identityM[1, 1] = 1;
            identityM[2, 2] = 1;
            identityM[3, 3] = 1;

            return identityM;
        }




    }
}
